#ifndef STEPMOTOR_H
#define STEPMOTOR_H

#include "debug.h"
#include "sysTick.h"
#include <stm32f4xx.h>

// 控制引脚
#define STEPMOTOR_PA GPIO_Pin_2 // A引脚
#define STEPMOTOR_PB GPIO_Pin_3 // B引脚
#define STEPMOTOR_PC GPIO_Pin_4 // C引脚
#define STEPMOTOR_PD GPIO_Pin_5 // D引脚

// GPIO
#define STEPMOTOR_GPIO GPIOA                                                                 // GPIOA组
#define STEPMOTOR_GPIO_Pin (STEPMOTOR_PA | STEPMOTOR_PB | STEPMOTOR_PC | STEPMOTOR_PD)       // 电机引脚
#define STEPMOTOR_RCC_AHBPeriphClockCmd RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE) // 时钟使能

// 励磁方式
#define STEPMOTOR_PHASE_EXCITATION_A STEPMOTOR_PA, STEPMOTOR_PB, STEPMOTOR_PC, STEPMOTOR_PD                                                                                                                      // 单项励磁
#define STEPMOTOR_PHASE_EXCITATION_B STEPMOTOR_PA | STEPMOTOR_PB, STEPMOTOR_PB | STEPMOTOR_PC, STEPMOTOR_PC | STEPMOTOR_PD, STEPMOTOR_PD | STEPMOTOR_PA                                                          // 双项励磁
#define STEPMOTOR_PHASE_EXCITATION_AB STEPMOTOR_PA, STEPMOTOR_PA | STEPMOTOR_PB, STEPMOTOR_PB, STEPMOTOR_PB | STEPMOTOR_PC, STEPMOTOR_PC, STEPMOTOR_PC | STEPMOTOR_PD, STEPMOTOR_PD, STEPMOTOR_PD | STEPMOTOR_PA // 单双励磁

/**
 * @name 方向
 * @enum
 */
typedef enum tag_STEPMOTOR_DIRECTION {
    STEPMOTOR_DIRECTION_CW = 0, // 顺时针
    STEPMOTOR_DIRECTION_CCW = 1 // 逆时针
} STEPMOTOR_DIRECTION;

/**
 * @name 励磁方式
 * @enum
 */
typedef enum tag_STEPMOTOR_PHASE_EXCITATION {
    STEPMOTOR_PE_A = 0, // 单项励磁
    STEPMOTOR_PE_B = 1, // 双项励磁
    STEPMOTOR_PE_AB = 2 // 单双励磁
} STEPMOTOR_PHASE_EXCITATION;

/**
 * @name 电机初始化
 * @description
 * @function
 * @returns {void}
 * @requires []
 */
void stepMotor_init(void);

/**
 * @name 电机控制
 * @description
 * @function
 * @param {STEPMOTOR_DIRECTION} direction 方向
 * @param {STEPMOTOR_PHASE_EXCITATION} phaseExcitation 相位激励
 * @returns {void (*function)(void)}
 * @requires [direction,phaseExcitation]
 */
void (*stepMotor_control(const STEPMOTOR_DIRECTION direction, const STEPMOTOR_PHASE_EXCITATION phaseExcitation))(void);

#endif
